package com.karson.service.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.karson.common.constants.BusinessConstants;
import com.karson.common.constants.Constants;
import com.karson.common.model.AlbumComment;
import com.karson.common.request.CommentRequest;
import com.karson.common.response.*;
import com.karson.common.util.DateUtil;
import com.karson.common.vo.ActionStatusVo;
import com.karson.common.vo.MemberVo;
import com.karson.service.service.AlbumCommentService;
import com.karson.service.dao.AlbumCommentMapper;
import com.karson.service.service.UserActionService;
import com.karson.service.service.UserService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
* @author ZKS
* @description 针对表【ar_album_comment(评论表)】的数据库操作Service实现
* @createDate 2025-09-13 11:15:32
*/
@Service
public class AlbumCommentServiceImpl extends ServiceImpl<AlbumCommentMapper, AlbumComment>
    implements AlbumCommentService{
    @Autowired
    private AlbumCommentMapper albumCommentMapper;
    @Autowired
    private UserActionService actionService;
    @Autowired
    private UserService userService;

    private static final Integer CURSOR_SIZE = 20;
    @Override
    public RepliesResponse pageList(String offset, Integer albumId, Integer orderType) throws JsonProcessingException {
        if (orderType == null) {
            orderType = Constants.ORDER_TIME;
        }

        Integer lastId = null;
        Integer lastLikeCount = null;
        LocalDateTime lastCreateTime = null;

        // 解析 offset
        if (offset != null) {
            String json = new String(Base64.getDecoder().decode(offset));
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> map = objectMapper.readValue(json, Map.class);

            lastId = map.get("id") != null ? ((Number) map.get("id")).intValue() : null;

            if (Constants.ORDER_LIKE.equals(orderType) && map.get("likeCount") != null) {
                lastLikeCount = ((Number) map.get("likeCount")).intValue();
            } else if (Constants.ORDER_TIME.equals(orderType) && map.get("createTime") != null) {
                // 使用 ISO-8601 格式解析
                lastCreateTime = LocalDateTime.parse((String) map.get("createTime"), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            }
        }

        // 查询当前页数据
        List<CommentResponse> responsePage = albumCommentMapper.selectByCursorMode(albumId, lastLikeCount, lastCreateTime, lastId, orderType, CURSOR_SIZE);
        responsePage.forEach(commentResponse -> {
            commentResponse.setSubReplyEntryText("共" + commentResponse.getReplyCount() + "条回复");
            String timeAgo = DateUtil.timeAgo(commentResponse.getCreateTime());
            commentResponse.setTimeDesc(timeAgo);
            List<CommentResponse> replies = commentResponse.getReplies();
            if (replies != null && !replies.isEmpty()) {
                int size = replies.size();
                int pick = new Random().nextInt(Math.min(size, 3) + 1);
                commentResponse.setReplies(replies.subList(0, pick));
                // 设置子评论时间描述
                commentResponse.getReplies().forEach(r -> r.setTimeDesc(DateUtil.timeAgo(r.getCreateTime())));
            }
        });
        // 查询顶置评论
        List<CommentResponse> topReplyList = albumCommentMapper.getTopReplyList(albumId, orderType);

        // 构建游标分页信息
        CursorPage page = new CursorPage();
        page.setBegin(offset == null);
        page.setEnd(responsePage.size() < CURSOR_SIZE);

        // 构建下一页 offset
        if (!responsePage.isEmpty()) {
            Map<String, Object> nextOffsetMap = getNextOffsetMap(orderType, responsePage);
            String nextOffsetJson = new ObjectMapper().writeValueAsString(nextOffsetMap);
            page.setNextOffset(Base64.getEncoder().encodeToString(nextOffsetJson.getBytes(StandardCharsets.UTF_8)));
        }

        page.setSessionId(RandomUtil.randomNumbers(4));
        // 设置用户状态
        getUserAction(responsePage);
        getUserAction(topReplyList);
        // 查询总数
        LambdaQueryWrapper<AlbumComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlbumComment::getMessageId, albumId);
        queryWrapper.eq(AlbumComment::getParentId, 0);
        Long totalCount = albumCommentMapper.selectCount(queryWrapper);
        page.setTotalCount(totalCount);

        // 构建响应
        RepliesResponse repliesResponse = new RepliesResponse();
        repliesResponse.setTopReplies(topReplyList);
        repliesResponse.setCursor(page);
        repliesResponse.setReplies(responsePage);

        return repliesResponse;
    }

    private void getUserAction(List<CommentResponse> replies) {
        replies.forEach(commentResponse -> {
            ActionStatusVo actionStatus = actionService.getActionStatus(commentResponse.getId(),BusinessConstants.BUSINESS_COMMENT);
            commentResponse.setUserActions(actionStatus);
            if (commentResponse.getReplies() != null && !commentResponse.getReplies().isEmpty()) {
                List<CommentResponse> replyList = commentResponse.getReplies();
                replyList.forEach(reply -> {
                    reply.setUserActions(actionService.getActionStatus(commentResponse.getId(), BusinessConstants.BUSINESS_COMMENT));
                });
            }
        });
    }

    @NotNull
    private static Map<String, Object> getNextOffsetMap(Integer orderType, List<CommentResponse> responsePage) {
        CommentResponse lastComment = responsePage.get(responsePage.size() - 1);
        Map<String, Object> nextOffsetMap = new HashMap<>(4);
        nextOffsetMap.put("id", lastComment.getId());
        if (Constants.ORDER_LIKE.equals(orderType)) {
            nextOffsetMap.put("likeCount", lastComment.getLike());
        } else if (Constants.ORDER_TIME.equals(orderType)) {
            // Date -> ISO-8601 字符串
            Date createTime = lastComment.getCreateTime();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            nextOffsetMap.put("createTime", sdf.format(createTime));
        }
        return nextOffsetMap;
    }

    /**
     * 分页获取子评论
     * @param page
     * @param albumId
     * @param orderType
     * @param rId
     * @return
     */
    @Override
    public IPage<CommentResponse> getPageList(IPage<CommentResponse> page, Integer albumId, Integer orderType, String rId) {
        IPage<CommentResponse> subCommentList = albumCommentMapper.getSubCommentList(page, albumId, orderType, rId);
        subCommentList.getRecords().forEach(commentResponse -> {
            String timeAgo = DateUtil.timeAgo(commentResponse.getCreateTime());
            commentResponse.setTimeDesc(timeAgo);
            ActionStatusVo actionStatus = actionService.getActionStatus(commentResponse.getId(), BusinessConstants.BUSINESS_COMMENT);
            commentResponse.setUserActions(actionStatus);
        });
        return subCommentList;
    }

    /**
     *  内容为json 格式 兼容页面路由跳转， 图片链接等操作
     *  评论内容为 根评论 二级评论 三级评论 之后没有区别
     *  主要通过rootId 以及 parentId 进行区分
     * @param request 请求参数
     * @return
     * @throws JsonProcessingException
     */
    @Override
    public CommentResponse addComment(CommentRequest request) throws JsonProcessingException {
        int uid = StpUtil.getLoginIdAsInt();
        if (request.getRootId() == null){
            request.setRootId(0);
        }
        if (request.getParentId() == null){
            request.setParentId(0);
        }
        AlbumComment albumComment = new AlbumComment();
        String content = request.buildContentJson();
        albumComment.setContent(content);
        albumComment.setMessageId(request.getAId());
        albumComment.setParentId(request.getParentId());
        albumComment.setRootId(request.getRootId());
        albumComment.setUserId(uid);
        //未审核
        albumComment.setStatus(2);
        albumCommentMapper.insert(albumComment);
        CommentResponse commentResponse = BeanUtil.copyProperties(albumComment, CommentResponse.class);
        commentResponse.setLike(0);
        commentResponse.setDislike(0);
        UserResponse info = userService.getInfo(uid);
        MemberVo memberVo = BeanUtil.copyProperties(info, MemberVo.class);
        commentResponse.setMember(memberVo);
        ActionStatusVo actionStatus = actionService.getActionStatus(commentResponse.getId(), BusinessConstants.BUSINESS_COMMENT);
        commentResponse.setUserActions(actionStatus);
        commentResponse.setCreateTime(new Date());
        commentResponse.setTimeDesc("刚刚");
        return commentResponse;
    }

    /**
     * 根据id删除评论， 注： 删除的评论是根评论，那么下面的子评论也会跟着删除
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delComment(Integer id) {
        AlbumComment albumComment = albumCommentMapper.selectById(id);
        if (albumComment == null) {
            return false;
        }
        Integer rootId = albumComment.getRootId();
        if (rootId != null && rootId == 0) {
            // 删除根评论，子评论也跟着删除
            //1、 获取当前根评论的子评论列表 ， 收集需要删除的id
            LambdaQueryWrapper<AlbumComment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AlbumComment::getRootId, id);
            queryWrapper.eq(AlbumComment::getMessageId, albumComment.getMessageId());
            List<AlbumComment> albumComments = albumCommentMapper.selectList(queryWrapper);
            albumComments.forEach(comment -> {
                comment.setStatus(3);
            });
            // 先删子评论
            updateBatchById(albumComments);
        }

        // 如果不是根评论直接删除就行
        albumComment.setStatus(3);
        updateById(albumComment);
        return true;
    }

    @Override
    public List<CommentTabsHeader> getTabsHeader() {
        List<CommentTabsHeader> headers = new ArrayList<>();
        CommentTabsHeader header1 = new CommentTabsHeader(0,"已审核的评论",1);
        CommentTabsHeader header2 = new CommentTabsHeader(0,"未审核的评论",2);
        CommentTabsHeader header3 = new CommentTabsHeader(0,"删除的评论",3);
        CommentTabsHeader header4 = new CommentTabsHeader(0,"屏蔽的评论",4);
        headers.add(header1);
        headers.add(header2);
        headers.add(header3);
        headers.add(header4);
        for (CommentTabsHeader header : headers) {
            LambdaQueryWrapper<AlbumComment> queryWrapper = new LambdaQueryWrapper<>();
            switch (header.getStatus()){
                case 1:
                    queryWrapper.eq(AlbumComment::getStatus,1);
                    queryWrapper.eq(AlbumComment::getRootId,0);
                    break;
                case 2:
                    queryWrapper.eq(AlbumComment::getStatus,2);
                    queryWrapper.eq(AlbumComment::getRootId,0);
                    break;
                case 3:
                    queryWrapper.eq(AlbumComment::getStatus,3);
                    queryWrapper.eq(AlbumComment::getRootId,0);
                    break;
                case 4:
                    queryWrapper.eq(AlbumComment::getStatus,4);
                    queryWrapper.eq(AlbumComment::getRootId,0);
                    break;
                default:
                    break;
            }
            List<AlbumComment> albumComments = albumCommentMapper.selectList(queryWrapper);
            header.setCount(albumComments.size());
        }
        return headers;
    }

    @Override
    public IPage<CommentAlbumResponse> getList(IPage<CommentAlbumResponse> commentPage, Integer albumId, Integer status) {
        return albumCommentMapper.getList(commentPage,albumId,status);
    }
}




